<style lang="sass" rel="stylesheet/scss">
    .datepicker-overlay {
        position: absolute;
        top: -200px;
        left: -400px;
        overflow: hidden;
        //background-color: #00FF00;
        width: 1300px;
        height: 800px;
    }

    .cov-date-body {
        position: absolute;
        top: 242px;
        left: 400px;
        background: #9b9b9b;
        overflow: hidden;
        font-size: 13px;
        font-family: 'Roboto';
        font-weight: 400;
        display: block;
        width: 253px;
        max-width: 100%;
        z-index: 999;
        border: 1px solid #ccc;
        /*border-radius: 4px;*/
        box-shadow: 2px 2px 12px rgba(0, 0, 0, 0.175);
    }

    .cov-datepicker {
        width: 255px;
    }

    .cov-picker-box {
        background: #fff;
        display: inline-block;
        padding: 16px;
        box-sizing: border-box !important;
        -moz-box-sizing: border-box !important;
        -webkit-box-sizing: border-box !important;
        -ms-box-sizing: border-box !important;
        width: 253px;
        max-width: 100%;
        height: 180px;
        text-align: start !important;
    }

    .cov-picker-box td {
        height: 24px;
        width: 24px;
        padding: 0;
        line-height: 24px;
        color: #000;
        background: #fff;
        text-align: center;
        cursor: pointer;
    }

    .cov-picker-box td:hover {
        background: #E6E6E6;
    }

    table {
        border-collapse: collapse;
        border-spacing: 0;
        width: 100%;
    }

    .day {
        width: 14.2857143%;
        display: inline-block;
        text-align: center;
        cursor: pointer;
        height: 24px;
        padding: 0;
        line-height: 24px;
        color: #000;
        background: #fff;
        vertical-align: middle;
    }

    .week ul {
        margin: 0 0 8px;
        padding: 0;
        list-style: none;
    }

    .week ul li {
        width: 14.2%;
        display: inline-block;
        text-align: center;
        background: transparent;
        color: #000;
        font-weight: bold;
    }

    .passive-day {
        color: #bbb;
    }

    .checked {
        background: #4da53c;
        color: #FFF !important;
        border-radius: 3px;
    }

    .unavailable {
        color: #ccc;
        cursor: not-allowed;
    }

    .cov-date-monthly {
        height: 50px;
    }

    .cov-date-monthly > div {
        display: inline-block;
        padding: 0;
        margin: 0;
        vertical-align: middle;
        color: #fff;
        height: 50px;
        float: left;
        text-align: center;
        cursor: pointer;
    }

    .cov-date-previous,
    .cov-date-next {
        overflow: hidden;
        color: #fff;
        i {
            display: inline-block;
            font-size: 20px;
            font-weight: bold;
            color: #ffffff;
            padding: 15px 9px;
        }
    }

    .cov-date-caption {
        width: 160px;
        box-sizing: border-box;
        font-size: 13px;
        padding: 16px 0;
        span {
            display: inline-block;
            padding-top: 8px;
        }
        .year {
            font-size: 16px;
        }
    }

    .cov-date-caption span:hover {
        color: rgba(255, 255, 255, 0.7);
    }

    .cov-date-previous:hover,
    .cov-date-next:hover {
        background: rgba(255, 255, 255, 0.1);
    }

    .day:hover {
        background: #EAEAEA;
    }

    .unavailable:hover {
        background: none;
    }

    .checked:hover {
        background: #1e97fc;
    }

    .date-item {
        text-align: center;
        font-size: 13px;
        padding: 10px 0;
        cursor: pointer;
    }

    .date-item:hover {
        background: #e0e0e0;
    }

    .date-list {
        overflow: auto;
        vertical-align: top;
        padding: 0;
    }

    .cov-vue-date {
        position: relative;
        display: inline-block;
        color: #5D5D5D;
    }

    .button-box {
        background: #fff;
        vertical-align: top;
        height: 24px;
        line-height: 24px;
        text-align: right;
        padding-right: 20px;
    }

    .button-box span {
        cursor: pointer;
        padding: 4px 0px;
    }

    .watch-box {
        height: 100%;
        overflow: hidden;
    }

    .hour-box,
    .min-box {
        display: inline-block;
        width: 50%;
        text-align: center;
        height: 100%;
        overflow: auto;
        float: left;
    }

    .hour-box ul,
    .min-box ul {
        list-style: none;
        margin: 0;
        padding: 0;
    }

    .hour-item,
    .min-item {
        padding: 10px;
        font-size: 36px;
        cursor: pointer;
    }

    .hour-item:hover,
    .min-item:hover {
        background: #E3E3E3;
    }

    .hour-box .active,
    .min-box .active {
        background: #1e97fc;
        color: #FFF !important;
    }

    /*::-webkit-scrollbar {*/
        /*width: 8px;*/
    /*}*/

    /*::-webkit-scrollbar-track {*/
        /*background: #E3E3E3;*/
    /*}*/

    /*::-webkit-scrollbar-thumb {*/
        /*background: #C1C1C1;*/
        /*border-radius: 2px;*/
    /*}*/
</style>
<template>
    <div class="cov-vue-date" :class="option.wrapperClass ? option.wrapperClass : {}">
        <div class="datepickbox">
            <input type="text"
                   :name="name"
                   title="input date"
                   class="cov-datepicker"
                   readonly="readonly"
                   :placeholder="option.placeholder"
                   v-model="date"
                   :required="required"
                   @click="showCheck"
                   @focus="showCheck"
                   :style="option.inputStyle ? option.inputStyle : {}"
                   :class="option.inputClass ? option.inputClass : {}"/>
        </div>
        <div class="datepicker-overlay" v-if="showInfo.check" @click="dismiss($event)">
            <div class="cov-date-body">
                <div class="cov-date-monthly">
                    <div class="cov-date-previous" @click="nextMonth('pre')"><i class="icon-arrow-left"></i></div>
                    <div class="cov-date-caption" :style="{'color': option.color ? option.color.headerText : '#fff'}">
                        <span @click="showYear" class="year">{{checked.year}}</span>
                        <br>
                        <span @click="showMonth" class="month">{{displayInfo.month}}</span>
                    </div>
                    <div class="cov-date-next" @click="nextMonth('next')"><i class="icon-arrow-right"></i></div>
                </div>
                <div class="cov-date-box" v-if="showInfo.day">
                    <div class="cov-picker-box">
                        <div class="week">
                            <ul>
                                <li v-for="weekie in library.week">{{weekie}}</li>
                            </ul>
                        </div>
                        <div class="day" v-for="day,index in dayList" :key="index" @click="checkDay(day)"
                             :class="{'checked':day.checked,'unavailable':day.unavailable,'passive-day': !(day.inMonth)}"
                             :style="day.checked ? (option.color && option.color.checkedDay ? { background: option.color.checkedDay } : { background: '#1e97fc' }) : {}">
                            {{day.value}}
                        </div>
                    </div>
                </div>
                <div class="cov-date-box list-box" v-if="showInfo.year">
                    <div class="cov-picker-box date-list" id="yearList">
                        <div class="date-item" v-for="yearItem,index in library.year" :key="index"
                             @click="setYear(yearItem)">{{yearItem}}
                        </div>
                    </div>
                </div>
                <div class="cov-date-box list-box" v-if="showInfo.month">
                    <div class="cov-picker-box date-list">
                        <div class="date-item" v-for="monthItem,index in library.month" :key="index"
                             @click="setMonth(monthItem)">{{monthItem}}
                        </div>
                    </div>
                </div>
                <div class="cov-date-box list-box" v-if="showInfo.hour">
                    <div class="cov-picker-box date-list">
                        <div class="watch-box">
                            <div class="hour-box">
                                <div class="mui-pciker-rule mui-pciker-rule-ft"></div>
                                <ul>
                                    <li class="hour-item" v-for="hitem in hours" @click="setTime('hour', hitem, hours)"
                                        :class="{'active':hitem.checked}">{{hitem.value}}
                                    </li>
                                </ul>
                            </div>
                            <div class="min-box">
                                <div class="mui-pciker-rule mui-pciker-rule-ft"></div>
                                <div class="min-item" v-for="mitem in mins" @click="setTime('min',mitem, mins)"
                                     :class="{'active':mitem.checked}">{{mitem.value}}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="button-box">
                    <span @click="showInfo.check=false">{{option.buttons? option.buttons.cancel : 'Cancel' }}</span>
                    <!--<span @click="picked">{{option.buttons? option.buttons.ok : 'Ok'}}</span>-->
                </div>
            </div>
        </div>
    </div>
</template>
<script>
    import moment from 'moment'
    export default {
        props: {
            required: false,
            start: {
                type: String,
                required: true
            },
            name:{
                type:String
            },
            defautStart:{
                type:String
            },
            option: {
                type: Object,
                default () {
                    return {
                        type: 'day',
                        SundayFirst: false,
                        week: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
                        month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
                        format: 'YYYY-MM-DD',
                        color: {
                            checked: '#1e97fc',
                            header: '#777777',
                            headerText: '#fff'
                        },
                        wrapperClass: '',
                        inputClass: '',
                        inputStyle: {
                            'display': 'inline-block',
                            'padding': '6px',
                            'line-height': '22px',
                            'font-size': '16px',
                            'border': '2px solid #fff',
                            'box-shadow': '0 1px 3px 0 rgba(0, 0, 0, 0.2)',
                            'border-radius': '2px',
                            'color': '#5F5F5F'
                        },
                        placeholder: 'when?',
                        buttons: {
                            ok: 'OK',
                            cancel: 'Cancel'
                        },
                        overlayOpacity: 0.5,
                        dismissible: true
                    }
                }
            },
            limit: {
                type: Array,
                default () {
                    return []
                }
            }
        },
        data () {
            function hours() {
                let list = []
                let hour = 24
                while (hour > 0) {
                    hour--
                    list.push({
                        checked: false,
                        value: hour < 10 ? '0' + hour : hour
                    })
                }
                return list
            }

            function mins() {
                let list = []
                let min = 60
                while (min > 0) {
                    min--
                    list.push({
                        checked: false,
                        value: min < 10 ? '0' + min : min
                    })
                }
                return list
            }

            return {
                date: this.start,
                displayDayView: false,
                unavailable: false,
                hours: hours(),
                mins: mins(),
                showInfo: {
                    hour: false,
                    day: false,
                    month: false,
                    year: false,
                    check: false
                },
                displayInfo: {
                    month: ''
                },
                library: {
                    week: this.option.week,
                    month: this.option.month,
                    year: []
                },
                checked: {
                    oldtime: '',
                    currentMoment: null,
                    year: '',
                    month: '',
                    day: '',
                    hour: '00',
                    min: '00'
                },
                dayList: [],
                selectedDays: [],
                showDefault:true
            }
        },
//        mounted () {
//            this._blur = (e) => {
//                debugger
//                if (this.$el !== null && !this.$el.contains(e.target)) {
//                    this.close()
//                }
//            }
//            //this.$emit('child-created', this)
//            //this.currDdate = this.parse(this.value) || this.parse(new Date())
//            $(window).on('click', this._blur)
//        },
        methods: {
            close () {
                this.showInfo.check = false
            },
            pad (n) {
                n = Math.floor(n)
                return n < 10 ? '0' + n : n
            },
            nextMonth (type) {
                let next = null
                type === 'next' ? next = moment(this.checked.currentMoment).add(1, 'M') : next = moment(this.checked.currentMoment).add(-1, 'M')
                this.showDay(next)
            },
            showDay (time) {
                if(this.showDefault && this.defautStart&&!time){
                    this.checked.oldtime = this.defautStart;
                    this.checked.currentMoment = moment(this.defautStart, this.option.format);
                }else{
                    if (time === undefined || !Date.parse(time)) {
                        this.checked.currentMoment = moment()
                    } else {
                        this.checked.currentMoment = moment(time, this.option.format)
                    }
                }
                this.showOne('day')
                this.checked.year = moment(this.checked.currentMoment).format('YYYY')
                this.checked.month = moment(this.checked.currentMoment).format('MM')
                this.checked.day = moment(this.checked.currentMoment).format('DD')
                this.displayInfo.month = this.library.month[moment(this.checked.currentMoment).month()]
                let days = []
                let currentMoment = this.checked.currentMoment
                let firstDay = moment(currentMoment).date(1).day()
                // gettting previous and next month
                // let currentMonth = moment(currentMoment)
                let previousMonth = moment(currentMoment)
                let nextMonth = moment(currentMoment)
                nextMonth.add(1, 'months')
                previousMonth.subtract(1, 'months')
                let monthDays = moment(currentMoment).daysInMonth()
                let oldtime = this.checked.oldtime
                for (let i = 1; i <= monthDays; ++i) {
                    days.push({
                        value: i,
                        inMonth: true,
                        unavailable: false,
                        checked: false,
                        moment: moment(currentMoment).date(i)
                    })
                    if (i === Math.ceil(moment(currentMoment).format('D')) && moment(oldtime, this.option.format).year() === moment(currentMoment).year() && moment(oldtime, this.option.format).month() === moment(currentMoment).month()) {
                        days[i - 1].checked = true
                    }
                    this.checkBySelectDays(i, days)
                }
                if (firstDay === 0) firstDay = 7
                for (let i = 0; i < firstDay - (this.option.SundayFirst ? 0 : 1); i++) {
                    let passiveDay = {
                        value: previousMonth.daysInMonth() - (i),
                        inMonth: false,
                        action: 'previous',
                        unavailable: false,
                        checked: false,
                        moment: moment(currentMoment).date(1).subtract(i + 1, 'days')
                    }
                    days.unshift(passiveDay)
                }
                var passiveDaysAtFinal = 42 - days.length
                for (let i = 1; i <= passiveDaysAtFinal; i++) {
                    let passiveDay = {
                        value: i,
                        inMonth: false,
                        action: 'next',
                        unavailable: false,
                        checked: false,
                        moment: moment(currentMoment).add(1, 'months').date(i)
                    }
                    days.push(passiveDay)
                }
                if (this.limit.length > 0) {
                    this.limit.forEach((li, index) => {
                        switch (li.type) {
                            case 'fromto':
                                days = this.limitFromTo(li, days);
                                break;
                            case 'weekday':
                                days = this.limitWeekDay(li, days);
                                break
                        }
                    });
                }
                this.dayList = days
            },
            checkBySelectDays (d, days) {
                this.selectedDays.forEach(day => {
                    if (this.checked.year === moment(day).format('YYYY') && this.checked.month === moment(day).format('MM') && d === Math.ceil(moment(day).format('D'))) {
                        days[d - 1].checked = true
                    }
                })
            },
            limitWeekDay (limit, days) {
                days.map((day) => {
                    if (limit.available.indexOf(Math.floor(day.moment.format('d'))) === -1) {
                        day.unavailable = true
                    }
                })
                return days
            },
            limitFromTo (limit, days) {
                if (limit.from || limit.to) {
                    days.map((day) => {
                        if (this.getLimitCondition(limit, day)) {
                            day.unavailable = true
                        }
                    })
                }
                return days
            },
            getLimitCondition (limit, day) {
                let tmpMoment = moment(day.moment.year() + '-' + this.pad(day.moment.month() + 1) + '-' + this.pad(day.value))
                if (limit.from && !limit.to) {
                    return !tmpMoment.isAfter(limit.from)
                } else if (!limit.from && limit.to) {
                    return !tmpMoment.isBefore(limit.to)
                } else {
                    return !tmpMoment.isBetween(limit.from, limit.to)
                }
            },
            checkDay (obj) {
                if (obj.unavailable || obj.value === '') {
                    this.unavailable = true
                    return false
                } else {
                    this.unavailable = false
                }
                if (!(obj.inMonth)) {
                    this.nextMonth(obj.action)
                }
                if (this.option.type === 'day' || this.option.type === 'min') {
                    this.dayList.forEach((x) => {
                        x.checked = false
                    })
                    this.checked.day = this.pad(obj.value)
                    obj.checked = true
                } else {
                    let day = this.pad(obj.value)
                    let ctime = this.checked.year + '-' + this.checked.month + '-' + day
                    if (obj.checked === true) {
                        obj.checked = false
                        this.selectedDays.$remove(ctime)
                    } else {
                        this.selectedDays.push(ctime)
                        obj.checked = true
                    }
                }
                switch (this.option.type) {
                    case 'day':
                        this.picked()
                        break
                    case 'min':
                        this.showOne('hour')
                        // shift activated time items to visible position.
                        this.shiftActTime()
                        break
                }
                this.showDefault = false;
            },
            showYear () {
                let year = moment(this.checked.currentMoment).year()
                this.library.year = []
                let yearTmp = []
                let yearLimit = moment().year() - 80;
                for (let i = yearLimit; i < year + 5; ++i) {
                    yearTmp.push(i)
                }

//                for (let i = year - 80; i < year + 5; ++i) {
//                    yearTmp.push(i)
//                }
                this.library.year = yearTmp
                this.showOne('year')
                this.$nextTick(() => {
                    let listDom = document.getElementById('yearList')
                    listDom.scrollTop = (listDom.scrollHeight - 100)
                    this.addYear()
                })
            },
            showOne (type) {
                switch (type) {
                    case 'year':
                        this.showInfo.hour = false
                        this.showInfo.day = false
                        this.showInfo.year = true
                        this.showInfo.month = false
                        break
                    case 'month':
                        this.showInfo.hour = false
                        this.showInfo.day = false
                        this.showInfo.year = false
                        this.showInfo.month = true
                        break
                    case 'day':
                        this.showInfo.hour = false
                        this.showInfo.day = true
                        this.showInfo.year = false
                        this.showInfo.month = false
                        break
                    case 'hour':
                        this.showInfo.hour = true
                        this.showInfo.day = false
                        this.showInfo.year = false
                        this.showInfo.month = false
                        break
                    default:
                        this.showInfo.day = true
                        this.showInfo.year = false
                        this.showInfo.month = false
                        this.showInfo.hour = false
                }
            },
            showMonth () {
                this.showOne('month')
            },
            addYear () {
                let listDom = document.getElementById('yearList')
                listDom.addEventListener('scroll', (e) => {
                    if (listDom.scrollTop < listDom.scrollHeight - 100) {
                        let len = this.library.year.length
                        let lastYear = this.library.year[len - 1]
                        this.library.year.push(lastYear + 1)
                    }
                }, false)
            },
            setYear (year) {
                this.checked.currentMoment = moment(year + '-' + this.checked.month + '-' + this.checked.day)
                this.showDefault = false;
                this.showDay(this.checked.currentMoment)
            },
            setMonth (month) {
                let mo = (this.library.month.indexOf(month) + 1)
                if (mo < 10) {
                    mo = '0' + '' + mo
                }
                this.checked.currentMoment = moment(this.checked.year + '-' + mo + '-' + this.checked.day)
                this.showDefault = false;
                this.showDay(this.checked.currentMoment)

            },
            showCheck () {
                if (this.date === '') {
                    this.showDay()
                } else {
                    if (this.option.type === 'day' || this.option.type === 'min') {
                        this.checked.oldtime = this.date
                        this.showDay(this.date)
                    } else {
                        this.selectedDays = JSON.parse(this.date)
                        if (this.selectedDays.length) {
                            this.checked.oldtime = this.selectedDays[0]
                            this.showDay(this.selectedDays[0])
                        } else {
                            this.showDay()
                        }
                    }
                }
                this.showInfo.check = true
            },
            setTime (type, obj, list) {
                list.forEach((item, index) => {
                    item.checked = false
                    if (item.value === obj.value) {
                        item.checked = true
                        this.checked[type] = item.value
                    }
                });
            },
            picked () {
                if (this.unavailable) {
                    return false;
                } else if (this.option.type === 'day' || this.option.type === 'min') {
                    let ctime = this.checked.year + '-' + this.checked.month + '-' + this.checked.day + ' ' + this.checked.hour + ':' + this.checked.min
                    this.checked.currentMoment = moment(ctime, 'YYYY-MM-DD HH:mm')
                    this.date = moment(this.checked.currentMoment).format(this.option.format)
                } else {
                    this.date = JSON.stringify(this.selectedDays)
                }
                this.showInfo.check = false
//                this.$emit('change', this.date);
                this.$emit('changeDay', this.date);
            },
            dismiss (evt) {
                if (evt.target.className === 'datepicker-overlay') {
                    if (this.option.dismissible === undefined || this.option.dismissible) {
                        this.showInfo.check = false
                        this.$emit('cancel')
                    }
                }
            },
            shiftActTime () {
                // shift activated time items to visible position.
                this.$nextTick(() => {
                    if (!document.querySelector('.hour-item.active')) {
                        return false
                    }
                    document.querySelector('.hour-box').scrollTop = (document.querySelector('.hour-item.active').offsetTop || 0) - 250
                    document.querySelector('.min-box').scrollTop = (document.querySelector('.min-item.active').offsetTop || 0) - 250
                })
            }
        }
    }
</script>
